<?php

/**
 * Ignus Framework
 *
 * @author Sergey Palyanov <sergey.palyanov@gmail.com>
 * @link http://code.google.com/p/ignus-php/
 * @license http://apache.org/licenses/LICENSE-2.0
 * @package Ignus
 * @subpackage Test
 * @since 0.1
 */

namespace Ignus\Test;

/**
 * @package Ignus
 * @subpackage Test
 * @since 0.1
 */
class Assert
{
    /**
     * No constructor for utility class available
     */
    private function __construct()
    {
    }

    /**
     * Just throws an assertion exception
     * @param string $message[optional]
     * @todo pass assert point code line from stacktrace to exception
     */
    public static function fail($message = "")
    {
        throw new AssertionException($message);
    }

    /**
     * Basic assertion checker, directly or not used by others
     * @param mixed $assertion Assertion
     * @param string $message Optional descriptive message
     */
    public static function assertTrue($assertion, $message = "")
    {
        if (!$assertion) {
            self::fail($message);
        }
    }

    /**
     * Asserts falsity of some expression
     * @param mixed $assertion Assertion
     * @param string $message Optional descriptive message
     */
    public static function assertFalse($assertion, $message = "")
    {
        self::assertTrue(!$assertion, $message);
    }

    /**
     * Asserts equality of some values
     * @param mixed $actual Value to check
     * @param mixed $expected Value to compare to
     * @param string $message Optional descriptive message
     */
    public static function assertEquals($actual, $expected, $message = "")
    {
        self::assertTrue($actual == $expected, $message);
    }

    /**
     * Does the opposite of assertEquals
     * @param mixed $actual Value to check
     * @param mixed $expected Value to compare to
     * @param string $message Optional descriptive message
     */
    public static function assertNotEquals($actual, $expected, $message = "")
    {
        self::assertTrue($actual != $expected, $message);
    }

    /**
     * For objects, asserts their referencing to same object. For arrays
     * it checks equality with elements ordering and data types matching.
     * For other data types it does equality testing with data types matching.
     * @param mixed $actual Value to check
     * @param mixed $expected Value to compare to
     * @param string $message Optional descriptive message
     */
    public static function assertSame($actual, $expected, $message = "")
    {
        self::assertTrue($actual === $expected, $message);
    }

    /**
     * Does the opposite of assertSame
     * @param mixed $actual Value to check
     * @param mixed $expected Value to compare to
     * @param string $message Optional descriptive message
     */
    public static function assertNotSame($actual, $expected, $message = "")
    {
        self::assertTrue($actual !== $expected, $message);
    }

    /**
     * Checks whether value is in range $min..$max or not
     * @param mixed $value Value to check
     * @param mixed $min Minimum value, inclusive
     * @param mixed $max Maximum value, inclusive
     * @param mixed $message Optional descriptive message
     */
    public static function assertInRange($value, $min, $max, $message = "")
    {
        self::assertTrue($value >= $min && $value <= $max, $message);
    }
}
